package selef.xiafan.service.impl;

import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import selef.xiafan.dao.*;
import selef.xiafan.entity.system.SysPermission;
import selef.xiafan.entity.system.SysRole;
import selef.xiafan.entity.system.SysRolePermission;
import selef.xiafan.entity.user.SysUserRole;
import selef.xiafan.entity.user.User;
import selef.xiafan.query.SysPermissionQ;
import selef.xiafan.service.ISysPermissionService;
import selef.xiafan.util.result.PageResult;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author xiafan
 * @version 1.0
 * @date 2021/7/1 23:14
 */
@Service
public class ISysPermissionServiceImpl implements ISysPermissionService {
    @Autowired
    private SysPermissionDao sysPermissionDao;
    @Autowired
    private SysRoleDao sysRoleDao;
    @Autowired
    private SysRolePermissionDao sysRolePermissionDao;
    @Autowired
    private SysUserRoleDao sysUserRoleDao;
    @Autowired
    private UserDao userDao;

    @Override
    public List<SysPermission> list() {
        return null;
    }

    @Override
    public Set<String> listPermissionURLsByUser(String name) {
        List<Integer> rids = sysRoleDao.findAllByName(name)
                .stream().map(SysRole::getId).collect(Collectors.toList());

        List<Integer> pids = sysRolePermissionDao.findAllByRidIn(rids)
                .stream().map(SysRolePermission::getPid).collect(Collectors.toList());

        List<SysPermission> perms = sysPermissionDao.findAllById(pids);

        Set<String> URLs = perms.stream().map(SysPermission::getUrl).collect(Collectors.toSet());

        return URLs;
    }

    /*
     * 判断用户请求接口的是否在权限列表中。如果没有对应权限，说明不需要维护
     * */
    @Override
    public boolean needFilter(String requestAPI) {
        List<SysPermission> ps = sysPermissionDao.findAll();
        for (SysPermission p : ps) {
            if (p.getUrl().equals(requestAPI)) {
                return true;
            }
        }
        return false;
    }

    /*
     * 先根据用户id查询角色id
     * 根据角色id查询权限id
     * 根据权限id查询所有数据
     * */
    @Override
    public Set<String> findUrlByUserid(User user) {
        Integer id = user.getId();
        List<Integer> rids = sysUserRoleDao.findAllByUid(id)
                .stream().map(SysUserRole::getRid).collect(Collectors.toList());
        List<Integer> pids = sysRolePermissionDao.findAllByRidIn(rids)
                .stream().map(SysRolePermission::getPid).collect(Collectors.toList());
        List<SysPermission> perms = sysPermissionDao.findAllById(pids);
        Set<String> URLs = perms.stream().map(SysPermission::getUrl).collect(Collectors.toSet());
        return URLs;
    }

    @Override
    public List<SysPermission> getAll() {
        return sysPermissionDao.findAll();
    }

    @Override
    public List<SysPermission> findAllById(Integer rid) {
        List<Integer> pid = sysRolePermissionDao.findAllByRid(rid)
                .stream().map(SysRolePermission::getPid).collect(Collectors.toList());
        // 根据角色拥有的权限id查询权限
        List<SysPermission> collect = sysPermissionDao.findAllById(pid)
                .stream().distinct().collect(Collectors.toList());
//        handlePermission(collect);
//        System.out.println("collect"+collect);
//        handpermsMenu(collect);
        return collect;
    }

    @Override
    public List<SysPermission> getMenusByCurrentUser() {
        String username = SecurityUtils.getSubject().getPrincipal().toString();
        User user = userDao.findByUsername(username);

        //根据用户信息查询角色信息
        List<Integer> roleId = sysUserRoleDao.findAllByUid(user.getId())
                .stream().map(SysUserRole::getRid).collect(Collectors.toList());

        List<Integer> permissionId = sysRolePermissionDao.findAllByRidIn(roleId)
                .stream().map(SysRolePermission::getPid).collect(Collectors.toList());
        List<SysPermission> listPermissions = sysPermissionDao.findAllById(permissionId)
                .stream().distinct().collect(Collectors.toList());
        handlePermission(listPermissions);
        return listPermissions;
    }

    @Override
    public PageResult<SysPermission> listPermission(SysPermissionQ sysPermissionQ) {
        Integer page = (sysPermissionQ.getPage() - 1) * sysPermissionQ.getSize();
        Integer size = sysPermissionQ.getSize();
        String nameZhForQuery = sysPermissionQ.getNameZh();

        if (nameZhForQuery == null || nameZhForQuery == "") {
            Long total = sysPermissionDao.countAll();
            if (total == 0L) {
                return new PageResult<>();
            }
            List<SysPermission> sysPermissionPageResult = sysPermissionDao.findAllNoQuery(page, size);
            return new PageResult<>(total, sysPermissionPageResult);
        }
            Long total = sysPermissionDao.countAllByQuery(nameZhForQuery);
        List<SysPermission> sysPermissionPageResult = sysPermissionDao.findAllByQuery(page, size, nameZhForQuery);
        return new PageResult<>(total, sysPermissionPageResult);

    }

    /*查询所有权限--用于菜单
     * 1.根据传递的角色id查询角色与权限中间表的权限id
     * 2.根据权限id查询权限集合
     * */
    @Override
    public List<SysPermission> getMenuList(Integer roleId) {
        List<Integer> permissionId = sysRolePermissionDao.findAllByRid(roleId)
                .stream().map(SysRolePermission::getPid).collect(Collectors.toList());

        List<SysPermission> listPermissionMenu = sysPermissionDao.findAllById(permissionId)
                .stream().distinct().collect(Collectors.toList());
        handlePermission(listPermissionMenu);
        return listPermissionMenu;
    }

    @Override
    public int addOrUpdate(SysPermission sysPermission) {
        // 添加
        if (sysPermission.getId() == null) {
            // 根据父id查询其路径，拼接现在的组件路径
            SysPermission byParentId = new SysPermission();
            if (sysPermission.getParentId() != 0) { // 添加的权限不是父节点时
                byParentId = sysPermissionDao.findById(sysPermission.getParentId()).get();
                sysPermission.setUrl("/system/" + sysPermission.getUrl());

                // 当组件名中存在子路径时，获取到下一个‘/’
                int next = sysPermission.getComponentName().indexOf("/");
                if (next != -1) {
                    String componentName = sysPermission.getComponentName();
                    String head = componentName.substring(0, next).toLowerCase();
                    String last = componentName.substring(next, componentName.length());
                    sysPermission.setComponent(byParentId.getUrl().substring(8, byParentId.getUrl().length()) + "/" + head + last); // 根据父路径拼接子路径
                    sysPermission.setComponentName(componentName.substring(next + 1, componentName.length()));
                } else {// 直接在父路径中添加
                    sysPermission.setComponent(byParentId.getUrl().substring(8,byParentId.getUrl().length())+"/"+sysPermission.getComponentName());
                }
            }
            // 添加根节点时
            if (sysPermission.getParentId() == 0) {
                sysPermission.setUrl("/system/" + sysPermission.getUrl());
                sysPermission.setComponent("SystemIndex");
            }
            sysPermissionDao.save(sysPermission);
            // 添加关联表信息
            SysPermission queryByName = sysPermissionDao.findByName(sysPermission.getName());
            SysRolePermission sysRolePermission = new SysRolePermission();
            sysRolePermission.setRid(1);
            sysRolePermission.setPid(queryByName.getId());
            sysRolePermissionDao.save(sysRolePermission);
            return 1;
        }
        // 修改判断条件：判断是否存在id
        if (sysPermission.getId() != null) {
            SysPermission byParentId = null;
            // 修改子节点
            if (sysPermission.getParentId() != 0) {
                byParentId = sysPermissionDao.findById(sysPermission.getParentId()).get();

                // 组件名存在子路径时
                int next = sysPermission.getComponentName().indexOf("/");
                if (next != -1) {
                    String componentName = sysPermission.getComponentName();
                    String head = componentName.substring(0, next).toLowerCase();
                    String last = componentName.substring(next, componentName.length());
                    sysPermission.setComponent(byParentId.getUrl().substring(8, byParentId.getUrl().length()) + "/" + head + last);
                    sysPermission.setComponentName(componentName.substring(next + 1, componentName.length()));
                } else { // 不存在子路径时
                    sysPermission.setComponent(byParentId.getUrl().substring(8, byParentId.getUrl().length()) + "/" + sysPermission.getComponentName());
                    sysPermission.setUrl("/system/" + sysPermission.getUrl());
                }
            }
            // 修改父节点
            if (sysPermission.getParentId() == 0) {
                sysPermission.setUrl("/system/" + sysPermission.getUrl());
                sysPermission.setComponent("SystemIndex");
                // 父节点不允许移动
                if (sysPermission.getParentId() != 0) {
                    return 3;
                }
            }
            sysPermissionDao.save(sysPermission);
            return 2;
        }
        return 4;
    }

    @Transactional
    @Override
    public int delete(SysPermission sysPermission) {
        //删除子节点时
        if (sysPermission.getParentId() != 0) {
            sysPermissionDao.deleteById(sysPermission.getId());
            sysRolePermissionDao.deleteAllByPid(sysPermission.getId());
            return 0;
        }
        // 如果删除父节点
        if (sysPermission.getParentId() == 0) {
            // 根据父id查询子集合
            List<SysPermission> collect = sysPermissionDao.findAllByParentId(sysPermission.getParentId());
            if (collect.size() != 0) {
                return 1; // 该父节点下存在子节点，不能删除
            }
        }
        return 2;
    }

    @Override
    public List<SysPermission> getAllByParentId(Integer parentId) {
        return sysPermissionDao.findAllByParentId(parentId);
    }

    public void handlePermission(List<SysPermission> permissionList) {
        permissionList.forEach(sysPermission -> {
            // 查询出来的结果是父节点下的所有数据
            List<SysPermission> childId = getAllByParentId(sysPermission.getId());
            sysPermission.setChildren(childId);
        });
        permissionList.removeIf(sysPermission -> sysPermission.getParentId() != 0);
    }

    /*
     * 将角色拥有的权限菜单处理为父子结构
     * 传递的参数是当前角色拥有的权限菜单
     * */
    public void handpermsMenu(List<SysPermission> permissionList) {
        permissionList.forEach(sysPermission -> {
            if (sysPermission.getParentId() == 0) {

            }
        });
        permissionList.removeIf(sysPermission -> sysPermission.getParentId() != 0);
    }

}
